include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckTypeSize)
include(CheckStructExists)

check_include_files(syslog.h HAVE_SYSLOG_H)
check_include_files(openssl/ssl.h HAVE_OPENSSL_H)
check_include_files(pthread.h HAVE_PTHREAD_H)

check_symbol_exists(LOG_EMERG   "syslog.h" HAVE_LOG_EMERG_S)
check_symbol_exists(LOG_ALERT   "syslog.h" HAVE_LOG_ALERT_S)
check_symbol_exists(LOG_CRIT    "syslog.h" HAVE_LOG_CRIT_S)
check_symbol_exists(LOG_ERR     "syslog.h" HAVE_LOG_ERR_S)
check_symbol_exists(LOG_WARNING "syslog.h" HAVE_LOG_WARNING_S)
check_symbol_exists(LOG_NOTICE  "syslog.h" HAVE_LOG_NOTICE_S)
check_symbol_exists(LOG_INFO    "syslog.h" HAVE_LOG_INFO_S)
check_symbol_exists(LOG_DEBUG   "syslog.h" HAVE_LOG_DEBUG_S)

set(CMAKE_EXTA_INCLUDE_FILES sys/types.h)
check_type_size("off_t" OFFT_SIZE)
check_type_size("off64_t" OFF64T_SIZE)
set(CMAKE_EXTA_INCLUDE_FILES)

set(CMAKE_EXTA_INCLUDE_FILES unistd.h)
check_type_size("ssize_t" SSIZET_SIZE)
check_type_size("size_t" SIZET_SIZE)
set(CMAKE_EXTA_INCLUDE_FILES)

check_struct_exists("struct stat" "sys/types.h;sys/stat.h" HAVE_STAT_R)
check_struct_exists("struct stat64" "sys/types.h;sys/stat.h" HAVE_STAT64_R)

check_symbol_exists(O_LARGEFILE "bits/fcntl.h" HAVE_LARGEFILE_S)
check_function_exists(open64 HAVE_OPEN64_F)
check_function_exists(lseek64 HAVE_LSEEK64_F)
check_function_exists(lstat64 HAVE_LSTAT64_F)

# TODO
# find a better check for POSIX compatible strerror_r behavior

macro(BACKTORY_INTERNAL_TEST_RUN BACKTORY_TEST)
	if("${BACKTORY_TEST}_COMPILE" MATCHES "^${BACKTORY_TEST}_COMPILE$")
		set(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${BACKTORY_TEST} ${CMAKE_REQUIRED_FLAGS}")
		#set(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${BACKTORY_TEST}")

		if(CMAKE_REQUIRED_LIBRARIES)
			set(BACKTORY_TEST_ADD_LIBRARIES "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
		endif(CMAKE_REQUIRED_LIBRARIES)
		
		message(STATUS "Performing backtory Test ${BACKTORY_TEST}")
		try_run(
			${BACKTORY_TEST}
			${BACKTORY_TEST}_COMPILE
			${CMAKE_BINARY_DIR}
			${backtory_SOURCE_DIR}/../CMake/tests.c
			CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
			"${BACKTORY_TEST_ADD_LIBRARIES}"
			OUTPUT_VARIABLE OUTPUT
		)
		
		if(${BACKTORY_TEST}_COMPILE AND NOT ${BACKTORY_TEST})
			set(${BACKTORY_TEST} 1 CACHE INTERNAL "backtory test ${FUNCTION}")
			message(STATUS "Performing backtory Test ${BACKTORY_TEST} - Success")
		else(${BACKTORY_TEST}_COMPILE AND NOT ${BACKTORY_TEST})
			message(STATUS "Performing backtory Test ${BACKTORY_TEST} - Failed")
			set(${BACKTORY_TEST} "" CACHE INTERNAL "backtory test ${FUNCTION}")
			file(
				APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
				"Performing backtory Test ${BACKTORY_TEST} failed with the following output:\n"
				"${OUTPUT}"
			)
			if(${BACKTORY_TEST}_COMPILE)
				file(
					APPEND
					"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
					"There was a problem running this test\n"
				)
			endif(${BACKTORY_TEST}_COMPILE)
			file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" "\n\n")
		endif(${BACKTORY_TEST}_COMPILE AND NOT ${BACKTORY_TEST})
	endif("${BACKTORY_TEST}_COMPILE" MATCHES "^${BACKTORY_TEST}_COMPILE$")
endmacro(BACKTORY_INTERNAL_TEST_RUN)

# Run test macro for several tests
foreach(BACKTORY_TEST
	HAVE_GLIBC_STRERROR_R
	HAVE_POSIX_STRERROR_R
	)
	backtory_internal_test_run(${BACKTORY_TEST})
endforeach(BACKTORY_TEST)

configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)